import 'dart:convert';
import 'dart:io';

import 'package:device_info_plus/device_info_plus.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:o2oa_all_platform/common/extension/index.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:local_auth/local_auth.dart';
import 'package:local_auth_android/local_auth_android.dart';
import 'package:local_auth_darwin/local_auth_darwin.dart';
import 'package:url_launcher/url_launcher.dart';

import '../../environment_config.dart';
import '../../pages/common/preview_image/index.dart';
import '../../pages/common/share_file/index.dart';
import '../../pages/common/video_player/index.dart';
import '../api/index.dart';
import '../routers/index.dart';
import '../services/index.dart';
import '../widgets/index.dart';
import 'flutter_mehod_channel_util.dart';
import 'loading.dart';
import 'log_util.dart';
import 'o2_api_manager.dart';
import 'webscoket_util.dart';

typedef OnFilePicker = void Function(List<String?> paths);

class O2Utils {
  /// 苹果电脑的文档
  static bool isAppleFile(String filePath) {
    final ext = filePath.toLowerCase();
    return ext.endsWith(".numbers") ||
        ext.endsWith(".pages") ||
        ext.endsWith(".key");
  }

  static bool isPPT(String filePath) {
    final ext = filePath.toLowerCase();
    return ext.endsWith(".ppt") || ext.endsWith(".pptx");
  }

  static bool isWord(String filePath) {
    final ext = filePath.toLowerCase();

    return ext.endsWith(".doc") || ext.endsWith(".docx");
  }

  static bool isExcel(String filePath) {
    final ext = filePath.toLowerCase();

    return ext.endsWith(".xls") || ext.endsWith(".xlsx");
  }

  static bool isPDF(String filePath) {
    return filePath.toLowerCase().endsWith(".pdf");
  }

  static bool isTxt(String filePath) {
    return filePath.toLowerCase().endsWith(".txt");
  }

  static bool isLog(String filePath) {
    return filePath.toLowerCase().endsWith(".log");
  }

  static bool isMarkdown(String filePath) {
    return filePath.toLowerCase().endsWith(".md");
  }

  static Future<void> logout({bool hasToken = true}) async {
    Loading.show();
    // websocket 断开
    O2WebsocketClient().stop();
    if (GetPlatform.isMobile && hasToken) {
      await _unbindDeviceForJpush();
    }
    // 登出
    await OrgAuthenticationService.to.logout();
    // 清除保存的用户信息
    await O2ApiManager.instance.cleanUser();
    // 关闭极速打卡
    FastCheckInService.instance.stop();
    Loading.dismiss();
    var routePath = Get.currentRoute;
    if (EnvironmentConfig.o2AppIsDemo && O2OARoutes.demoLogin != routePath) {
      Get.offAllNamed(O2OARoutes.demoLogin);
    } else if (O2OARoutes.login != routePath) {
      Get.offAllNamed(O2OARoutes.login);
    }
  }

  // 设置横屏
  static Future<void> setLandscape() async {
    await SystemChrome.setPreferredOrientations(
        [DeviceOrientation.landscapeRight, DeviceOrientation.landscapeLeft]);
    if (Platform.isAndroid) {
      ///关闭状态栏，与底部虚拟操作按钮
      await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
          overlays: []);
    }
  }

  // 设置竖屏
  static Future<void> setPortrait() async {
    await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
    if (Platform.isAndroid) {
      ///显示状态栏，与底部虚拟操作按钮
      await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
          overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]);
    }
  }

  static Future<void> _unbindDeviceForJpush() async {
    var deviceId = O2ApiManager.instance.deviceID;
    if (deviceId.isNotEmpty) {
      var result = await JpushAssembleControlService.to.unBindDevice(deviceId);
      if (result == null) {
        OLogger.e('设备号解除绑定失败！！！');
      }
    } else {
      OLogger.e('没有获取到极光推送的设备号！！！！！');
    }
  }

  static Map<String, dynamic> parseStringToJson(String jsonString) {
    try {
      final Map<String, dynamic> parsedJson = json.decode(jsonString);
      return parsedJson;
    } catch (e) {
      // JSON解析异常处理
      OLogger.e('解析JSON时出现异常: $e  json: $jsonString');
      return {};
    }
  }
  /// 格式化成 json 字符串
  static String json2String(dynamic data, {bool pretty = false}) {
    if (data is Map ||
        data is List ||
        data is String ||
        data is num ||
        data is bool) {
      try {
        if (pretty) {
          JsonEncoder encoder = const JsonEncoder.withIndent('  ');
          return encoder.convert(data);
        } else {
          return jsonEncode(data);
        }
      } catch (e) {
        OLogger.e('格式化失败: $e');
      }
    }
    return '';
  }

  ///
  ///判断是否手机号码
  ///中国的11位手机号码 和 香港澳门的 手机号码
  static bool isMobilePhoneNumber(String phoneNumber) {
    if (phoneNumber.isEmpty) {
      return false;
    }
    return GetUtils.hasMatch(phoneNumber, r'^(1)\d{10}$') ||
        GetUtils.hasMatch(phoneNumber, r'^((\+00)?(852|853)\d{8})$');
  }

  /// 判断存储权限
  ///
  static Future<bool> storagePermission() async {
    if (Platform.isAndroid) {
      final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
      AndroidDeviceInfo info = await deviceInfoPlugin.androidInfo;
      final sdk = info.version.sdkInt;
      if (sdk >= 33) {
        // Android sdk 33 以后没有storage权限了
        return true;
      }
    }
    var status = await Permission.storage.status;
    if (status == PermissionStatus.granted) {
      return true;
    } else {
      if (Platform.isAndroid) {
        O2OverlayEntryDialog.instance.openAlertDialog(
            'common_permission_storage_request_title'.tr,
            'common_permission_storage_request_content'.tr);
      }
      status = await Permission.storage.request();
      if (Platform.isAndroid) {
        O2OverlayEntryDialog.instance.closeDiloag();
      }
      if (status == PermissionStatus.granted) {
        return true;
      }
    }
    return false;
  }

  /// 摄像头权限判断
  static Future<bool> cameraPermission() async {
    var status = await Permission.camera.status;
    if (status == PermissionStatus.granted) {
      return true;
    } else {
      if (Platform.isAndroid) {
        O2OverlayEntryDialog.instance.openAlertDialog(
            'common_permission_camera_request_title'.tr,
            'common_permission_camera_request_content'.tr);
      }
      status = await Permission.camera.request();
      if (Platform.isAndroid) {
        O2OverlayEntryDialog.instance.closeDiloag();
      }
      if (status == PermissionStatus.granted) {
        return true;
      }
    }
    return false;
  }

  /// 定位权限判断
  static Future<bool> locationPermission() async {
    var status = await Permission.location.status;
    if (status == PermissionStatus.granted) {
      return true;
    } else {
      if (Platform.isAndroid) {
        O2OverlayEntryDialog.instance.openAlertDialog(
            'common_permission_location_request_title'.tr,
            'common_permission_location_request_content'.tr);
      }
      status = await Permission.location.request();
      if (Platform.isAndroid) {
        O2OverlayEntryDialog.instance.closeDiloag();
      }
      if (status == PermissionStatus.granted) {
        return true;
      }
    }
    return false;
  }

  /// 麦克风权限判断
  static Future<bool> microphonePermission() async {
    var status = await Permission.microphone.status;
    if (status == PermissionStatus.granted) {
      return true;
    } else {
      if (Platform.isAndroid) {
        O2OverlayEntryDialog.instance.openAlertDialog(
            'common_permission_microphone_request_title'.tr,
            'common_permission_microphone_request_content'.tr);
      }
      status = await Permission.microphone.request();
      if (Platform.isAndroid) {
        O2OverlayEntryDialog.instance.closeDiloag();
      }
      if (status == PermissionStatus.granted) {
        return true;
      }
    }
    return false;
  }

  /// 文件选择器
  /// @param callback  返回选择的文件结果
  static void pickerFileOrImage(OnFilePicker callback,
      {allowMultiple = false, List<String>? allowedExtensions}) {
    // ios 可以打开相册
    final context = Get.context;
    if (context == null) {
      callback([]);
      return;
    }
    List<Widget> menus = [];
    if (Platform.isIOS) {
      menus = [
        ListTile(
          onTap: () {
            Navigator.pop(context);
            _takePhoto(callback);
          },
          title: Align(
            alignment: Alignment.center,
            child: Text('take_photo'.tr,
                style: Theme.of(context).textTheme.bodyMedium),
          ),
        ),
        const Divider(height: 1),
        ListTile(
          onTap: () {
            Navigator.pop(context);
            _pickImage(callback);
          },
          title: Align(
            alignment: Alignment.center,
            child:
                Text('album'.tr, style: Theme.of(context).textTheme.bodyMedium),
          ),
        ),
        const Divider(height: 1),
        ListTile(
          onTap: () {
            Navigator.pop(context);
            _pickFiles(callback, allowMultiple,
                allowedExtensions: allowedExtensions);
          },
          title: Align(
            alignment: Alignment.center,
            child: Text('pick_file'.tr,
                style: Theme.of(context).textTheme.bodyMedium),
          ),
        ),
      ];
    } else {
      menus = [
        ListTile(
          onTap: () {
            Navigator.pop(context);
            _takePhoto(callback);
          },
          title: Align(
            alignment: Alignment.center,
            child: Text('take_photo'.tr,
                style: Theme.of(context).textTheme.bodyMedium),
          ),
        ),
        const Divider(height: 1),
        ListTile(
          onTap: () {
            Navigator.pop(context);
            _pickFiles(callback, allowMultiple,
                allowedExtensions: allowedExtensions);
          },
          title: Align(
            alignment: Alignment.center,
            child: Text('pick_file'.tr,
                style: Theme.of(context).textTheme.bodyMedium),
          ),
        ),
      ];
    }
    O2UI.showBottomSheetWithCancel(context, menus);
  }

  /// 直接拍照
  static void _takePhoto(OnFilePicker callback) async {
    if (!await O2Utils.cameraPermission()) {
      callback([]);
      return;
    }
    XFile? file = await ImagePicker().pickImage(source: ImageSource.camera);
    if (file != null) {
      callback([file.path]);
    } else {
      callback([]);
    }
  }

  /// 相册
  static void _pickImage(OnFilePicker callback) async {
    XFile? file = await ImagePicker().pickImage(source: ImageSource.gallery);
    if (file != null) {
      callback([file.path]);
    } else {
      callback([]);
    }
  }

  /// 文件选择
  static void _pickFiles(OnFilePicker callback, bool allowMultiple,
      {List<String>? allowedExtensions}) async {
    if (!await O2Utils.storagePermission()) {
      callback([]);
      return;
    }
    Loading.show();
    FilePickerResult? result = await FilePicker.platform.pickFiles(
        allowMultiple: allowMultiple,
        allowedExtensions: allowedExtensions,
        type: allowedExtensions == null || allowedExtensions.isEmpty
            ? FileType.any
            : FileType.custom);
    Loading.dismiss();
    if (result != null && result.paths.isNotEmpty) {
      callback(result.paths);
    } else {
      callback([]);
    }
  }

  static Future<bool> bioAuth() async {
    OLogger.d('点击了认证诶');
    try {
      final auth = LocalAuthentication();
      final didAuthenticate = await auth.authenticate(
          localizedReason: 'account_safe_local_auth_open_app'.tr,
          authMessages: [
            AndroidAuthMessages(
                biometricRequiredTitle:
                    'account_safe_local_auth_biometric_required'.tr,
                goToSettingsDescription:
                    'account_safe_local_auth_android_description'.tr,
                cancelButton: 'cancel'.tr,
                goToSettingsButton: 'account_safe_local_auth_go_to_setting'.tr,
                biometricNotRecognized:
                    'account_safe_local_auth_not_recognized'.tr,
                biometricHint: 'account_safe_local_auth_android_bio_hint'.tr,
                signInTitle:
                    'account_safe_local_auth_android_bio_sign_in_title'.tr),
            IOSAuthMessages(
              goToSettingsButton: 'account_safe_local_auth_go_to_setting'.tr,
              goToSettingsDescription:
                  'account_safe_local_auth_ios_description'.tr,
              cancelButton: 'cancel'.tr,
            )
          ],
          options: const AuthenticationOptions(biometricOnly: false));
      return didAuthenticate;
    } on PlatformException catch (e) {
      OLogger.e('认证失败', e);
    }
    return false;
  }

  static Future<void> openLocalFile(String filePath, String fileName,
      {bool shareBtnShow = true}) async {
    if (filePath.isImageFileName) {
      PreviewImagePage.open(filePath, fileName);
    } else if (filePath.isVideoFileName) {
      VideoPlayerPage.openLocalVideo(filePath, title: fileName);
    } else {
      if (GetPlatform.isDesktop) {
        // 使用本地软件打开文件
        final Uri uri = Uri.file(filePath);
        if (!await launchUrl(uri)) {
          // 无法打开？
          Loading.toast('im_msg_download_success'.tr);
        }
      } else {
        if (filePath.canPreviewFile) {
          O2FlutterMethodChannelUtils()
              .openLocalFile(filePath, shareBtnShow: shareBtnShow);
        } else {
          Get.to(
              () => ShareFilePage(shareFilePath: filePath, fileName: fileName));
        }
      }
    }
  }

  /// 盒子宽度和内部 item 宽度 计算放入个数
  static int calculateItemsPerRow(double width, double itemWidth) {
    const double spacing = 10;
    if (width <= 0) return 0;
    // 每个 item 实际占据的宽度（含 spacing，但最后一个 item 不需要 spacing）
    int count = ((width + spacing) / (itemWidth + spacing)).floor();
    return count;
  }
}
